package library.jaas;

import java.util.Map;

import javax.naming.InitialContext;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import library.IF.LibraryAdminIF;

/**
 * The Class MyLoginModule.
 * 
 * @author Matthijs Steen
 */
public class MyLoginModule implements LoginModule
{
	/** The subject. */
	private Subject subject;
	
	/** The callback handler. */
	private CallbackHandler callbackHandler;
	
	/** The user. */
	private MyPrincipal user;
	
	/** The roles. */
	private MyPrincipal[] roles;
	
	/* (non-Javadoc)
	 * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
	 */
	@Override
	public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options)
	{
		this.subject = subject;
		
		this.callbackHandler = callbackHandler;
	}
	
	/* (non-Javadoc)
	 * @see javax.security.auth.spi.LoginModule#login()
	 */
	@Override
	public boolean login() throws LoginException
	{
		NameCallback nameCallback = new NameCallback("Username");
		
		PasswordCallback passwordCallback = new PasswordCallback("Password", false);
		
		Callback[] callbacks = new Callback[] {nameCallback, passwordCallback};
		
		try
		{
			callbackHandler.handle(callbacks);
		}
		catch (Exception e)
		{
			return false;
		}
		
		String username = nameCallback.getName();
		
		System.out.println("username: " + username);
		
		String password = new String(passwordCallback.getPassword());
		passwordCallback.clearPassword();
		
		System.out.println("password: " + password);
		
		boolean succeeded = false;
		
		try
		{
			InitialContext ctx = new InitialContext();
			LibraryAdminIF libraryAdmin = (LibraryAdminIF) ctx.lookup("LibraryAdminBean/local");
			String[] roleNames = libraryAdmin.check(username, password);
			
			int i = 0;
			
			roles = new MyPrincipal[roleNames.length];
			
			for (String roleName: roleNames)
			{
				roles[i++] = new MyPrincipal(roleName);
			}
			
			succeeded = true;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			
			succeeded = false;
		}
		
		return succeeded;
	}
	
	/* (non-Javadoc)
	 * @see javax.security.auth.spi.LoginModule#commit()
	 */
	@Override
	public boolean commit() throws LoginException
	{
		MyGroup group;
		
		group = new MyGroup("CallerPrincipal");
		group.addMember(user);
		
		subject.getPrincipals().add(group);
		
		group = new MyGroup("Roles");
		
		for (MyPrincipal role: roles)
		{
			group.addMember(role);
		}
		
		subject.getPrincipals().add(group);
		
		return true;
	}
	
	/* (non-Javadoc)
	 * @see javax.security.auth.spi.LoginModule#logout()
	 */
	@Override
	public boolean logout() throws LoginException
	{
		return true;
	}
	
	/* (non-Javadoc)
	 * @see javax.security.auth.spi.LoginModule#abort()
	 */
	@Override
	public boolean abort() throws LoginException
	{
		return false;
	}
}
